package com.yzd.learnjava.concurrency;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SimpleMicroBenchmark {
	static long test(Incrementable in) {
		long start = System.nanoTime();
		for(long i = 0 ; i < 10000000L; i++) {
			in.increment();
		}
		return System.nanoTime() - start;
	}
	
	public static void main(String[] args) {
		Long syncTime = test(new SynchronizingTest());
		long lockTime = test(new LockingTest());
		
		System.out.printf("synchronized : %1$10d\n", syncTime);
		System.out.printf("lock         : %1$10d\n", lockTime);
		System.out.printf("lock / synchronized =  %1$.3f", (double)lockTime / (double)syncTime);
				
	}
}

abstract class Incrementable{
	protected long counter = 0;
	public abstract void increment();
}

class SynchronizingTest extends Incrementable{
	public synchronized void increment() {
		++counter;
	}
}

class LockingTest extends Incrementable{
	private Lock lock = new ReentrantLock();
	public void increment() {
		lock.lock();
		try {
			++counter;
		}finally {
			lock.unlock();
		}
	}
}
